#include <func.h>
#define MAXEV 3
int  nonblock(int fd)
{
    int flag;
    flag=fcntl(fd,F_GETFL);
    //flag|=O_NONBLOCK;
    flag&=~O_NONBLOCK;
    int ret=fcntl(fd,F_SETFL,flag);
    ERROR_CHECK(ret,-1,"fcntl");
    return 0;
}
int main(int argc,char *argv[])
{
    ARGS_CHECK(argc,3);
    int sockfd;
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    ERROR_CHECK(sockfd,-1,"socket");
    printf("sockfd=%d\n",sockfd);
    struct sockaddr_in ser;
    bzero(&ser,sizeof(ser));
    ser.sin_family=AF_INET;
    ser.sin_addr.s_addr=inet_addr(argv[1]);
    ser.sin_port=htons(atoi(argv[2]));
    int reuse=1;
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(const void*)&reuse,sizeof(int));
    int ret;
    ret=bind(sockfd,(struct sockaddr*)&ser,sizeof(struct sockaddr));
    ERROR_CHECK(ret,-1,"bind");
    listen(sockfd,10);
    int newfd;
    struct sockaddr_in cli;
    char buf[1024]={0};
    int epfd=epoll_create(1);
    ERROR_CHECK(epfd,-1,"epoll_create");
    struct epoll_event event,evlist[MAXEV];
    event.data.fd=sockfd;
    event.events=EPOLLIN;
    ret=epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&event);
    ERROR_CHECK(ret,-1,"epoll_ctl");
    event.data.fd=STDIN_FILENO;
    ret=epoll_ctl(epfd,EPOLL_CTL_ADD,STDIN_FILENO,&event);
    ERROR_CHECK(ret,-1,"epoll_ctl");
    int ready,i;
    int rcvlowat=5;
    while(1)
    {
        ready=epoll_wait(epfd,evlist,MAXEV,-1);
        ERROR_CHECK(ready,-1,"epoll_wait");
        for(i=0;i<ready;++i)
        {
            if(evlist[i].data.fd==sockfd)
            {
                bzero(&cli,sizeof(cli));
                socklen_t len=sizeof(cli);
                newfd=accept(sockfd,(struct sockaddr*)&cli,&len);
                ERROR_CHECK(newfd,-1,"accept");
                printf("client ip=%s,client port=%d\n",
                       inet_ntoa(cli.sin_addr),ntohs(cli.sin_port));
                //nonblock(newfd);
                setsockopt(newfd,SOL_SOCKET,SO_RCVLOWAT,&rcvlowat,sizeof(int));
                event.data.fd=newfd;
                event.events=EPOLLIN|EPOLLET;
                ret=epoll_ctl(epfd,EPOLL_CTL_ADD,newfd,&event);
                ERROR_CHECK(ret,-1,"epoll_ctl");
            }
            if(evlist[i].data.fd==newfd)
            {
                bzero(buf,sizeof(buf));
                ret=recv(newfd,buf,sizeof(buf)-1,0);
                printf("i=%d,ret=%d\n",i,ret);
                if(0==ret)
                {
                    printf("GooBye!\n");
                    //及时把newfd从兴趣列表中移除，避免newfd一直处于就绪态导致的疯狂打印
                    ret=epoll_ctl(epfd,EPOLL_CTL_DEL,newfd,&event);
                    ERROR_CHECK(ret,-1,"epoll_ctl");
                    close(newfd);
                    break;
                }else if(-1==ret){
                    printf("\n");
                    break;
                }else{
                //write(STDOUT_FILENO,buf,strlen(buf)-1);
                printf("%s",buf);
                }
            }
            if(evlist[i].data.fd==STDIN_FILENO)
            {
                bzero(buf,sizeof(buf));
                read(STDIN_FILENO,buf,sizeof(buf));
                send(newfd,buf,sizeof(buf)-1,0);
            }
        }
    }
    close(sockfd);
    return 0;
}

